#include <bits/stdc++.h>
using namespace std;

// 定义点的结构体
struct node {
  double x, y; // 点的x和y坐标
} a, b, c, d;  // 四个点：a->b是第一条线段，c->d是第二条线段

double len1, len2; // len1是线段ab的长度，len2是线段cd的长度

// 计算在时间l秒后，两个移动点的距离
double cal(double l) {
  double x1, x2, y1, y2;

  // 计算第一个点在时间l后的位置
  if (l >= len1)
    x1 = b.x, y1 = b.y; // 如果时间超过线段长度，到达终点b
  else
    // 按比例计算在线段ab上的位置
    x1 = a.x + (b.x - a.x) / len1 * l, y1 = a.y + (b.y - a.y) / len1 * l;

  // 计算第二个点在时间l后的位置
  if (l >= len2)
    x2 = d.x, y2 = d.y; // 如果时间超过线段长度，到达终点d
  else
    // 按比例计算在线段cd上的位置
    x2 = c.x + (d.x - c.x) / len2 * l, y2 = c.y + (d.y - c.y) / len2 * l;

  // 返回两点之间的欧几里得距离
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

void solve() {
  // 输入四个点的坐标
  cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> d.x >> d.y;

  // 计算两条线段的长度
  len1 = sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
  len2 = sqrt((c.x - d.x) * (c.x - d.x) + (c.y - d.y) * (c.y - d.y));

  double l = 0, r = min(len1, len2); // 初始化二分区间

  // 第一段三分查找：在两条线段都还在移动的时间范围内
  while (r - l >= 1e-9) {        // 精度控制
    double m1 = (2 * l + r) / 3; // 第一个三分点
    double m2 = (l + 2 * r) / 3; // 第二个三分点

    // 比较两个三分点的函数值，缩小搜索区间
    if (cal(m1) >= cal(m2))
      l = m1; // 如果m1点距离更大，说明最小值在右侧
    else
      r = m2; // 否则最小值在左侧
  }
  double ans = cal(l); // 记录第一段的最小距离

  // 第二段三分查找：当一条线段已经到达终点，另一条还在移动的时间范围内
  l = min(len1, len2), r = max(len1, len2);
  while (r - l >= 1e-9) {        // 精度控制
    double m1 = (2 * l + r) / 3; // 第一个三分点
    double m2 = (l + 2 * r) / 3; // 第二个三分点

    // 比较两个三分点的函数值，缩小搜索区间
    if (cal(m1) >= cal(m2) - 1e-9)
      l = m1; // 如果m1点距离更大，说明最小值在右侧
    else
      r = m2; // 否则最小值在左侧
  }

  // 取两段搜索中的最小值作为最终答案
  ans = min(ans, cal(l));

  // 输出结果，保留16位小数精度
  cout << fixed << setprecision(16) << ans << endl;
}

int main() {
  int T; // 测试用例数量
  cin >> T;
  while (T--)
    solve(); // 处理每个测试用例
  return 0;
}